package com.example.netty.dubborpc.netty;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.concurrent.Callable;

/**
 * @author Administrator
 */
public class NettyClientHandler extends ChannelInboundHandlerAdapter implements Callable<String> {

    private ChannelHandlerContext context; // 上下文
    private String result; // 返回的结果
    private String para; // 客户端调用方法时，传入的参数

    /**
     * 与服务器连接成功创建后，被调用 （1）
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // 在其他方法会使用到 ctx
        context = ctx;
    }

    /**
     * 收到服务器的数据后，调用方法 （4）
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        result = msg.toString();
        notify(); // 唤醒等待的线程
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }

    /**
     * 被代理对象调用，发送数据给服务器
     * -> 等待被唤醒 -> 放回结果(3) ->(5)
     * @return
     * @throws Exception
     */
    @Override
    public synchronized String call() throws Exception {
        context.writeAndFlush(para);
        // 进行 wait
        wait(); // 等待 channelRead 获取期到服务器的结果后，唤醒
        return result; // 服务方返回的结果
    }
    // (2)
    public void setPara(String para) {
        this.para = para;
    }
}
